/**
 * @author: Gene
 * @age: 永远18岁的美少年
 * @Email： yangjianyun@58.com
 * @date: 2021-11-25 20:37:47
 * @description: babel 核心的分析 以及自己实现一个 babel 插件
 */
// babel 的核心模块
const core = require("@babel/core")
//用来生成或判断节点的 AST 语法树的节点
let types = require("@babel/types")
// let arrowFunctionPlugin = require("babel-plugin-transform-es2015-arrow-functions")

/** ================ 自己实现 箭头函数转的插件 =========================== */
let arrowFunctionPlugin2 = {
    visitor: {
        // path 节点路径, 如果是箭头函数, 那么就会就来此函数, 参数是箭头函数节点的路径对象
        ArrowFunctionExpression(path) {
            // console.log(path);
            let node = path.node
            node.type = "FunctionExpression"
        }
    }
}
let sourceCode = `
    const sum = (a,b)=>{
        return a + b
    }
`
let targetSource = core.transform(sourceCode, {
    plugins: [arrowFunctionPlugin2]
})
// console.log("转换后的 targetSource -->>", targetSource.code);

/** =============  把类转换成 函数  ================*/
let transformClassesPlugin = require("@babel/plugin-transform-classes")
let transformClassesPlugin2 = {
    visitor: {
        // path 节点路径, 如果是箭头函数, 那么就会就来此函数, 参数是箭头函数节点的路径对象
        // path 代表路径 node代表路径上的一个节点
        ClassDeclaration(path) {
            let node = path.node;
            let id = node.id;//Identifier name:Person
            let methods = node.body.body;//Array<MethodDefinition>
            let nodes = [];
            methods.forEach(method => {
                if (method.kind === 'constructor') {
                    let constructorFunction = types.functionDeclaration(
                        id,
                        method.params,
                        method.body
                    );
                    nodes.push(constructorFunction);
                } else {
                    let memberExpression = types.memberExpression(
                        types.memberExpression(
                            id, types.identifier('prototype')
                        ), method.key
                    )
                    let functionExpression = types.functionExpression(
                        null,
                        method.params,
                        method.body
                    )
                    let assignmentExpression = types.assignmentExpression(
                        '=',
                        memberExpression,
                        functionExpression
                    );
                    nodes.push(assignmentExpression);
                }
            })
            if (nodes.length === 1) {
                //单节点用replaceWith
                //path代表路径，用nodes[0]这个新节点替换旧path上现有老节点node ClassDeclaration
                path.replaceWith(nodes[0]);
            } else {
                //多节点用replaceWithMultiple
                path.replaceWithMultiple(nodes);
            }
        },
        // ClassExpression(path) {
        //     // console.log(path);
        //     let node = path.node
        //     let id = node.id // 标识符
        //     let methods = node.body.body
        //     let nodes = []
        //     methods.forEach((method) => {
        //         if (method.kind === "constructor") {
        //             let constructorFunction = types.functionDeclaration(
        //                 id,
        //                 method.params,
        //                 method.body
        //             )
        //             nodes.push(constructorFunction)
        //         } else {
        //             let memberExpression = types.memberExpression(
        //                 types.memberExpression(
        //                     id, types.identifier("prototype")
        //                 ), method.key
        //             )
        //             let functionExpression = types.functionExpression(
        //                null,
        //                 method.params,
        //                 method.body
        //             )
        //             let assignmentExpression = types.assignmentExpression(
        //                 "=",
        //                 memberExpression,
        //                 functionExpression
        //             )
        //             nodes.push(assignmentExpression)
        //         }
        //     })
        //     if (nodes.length === 1) {
        //         // 单节点用 replaceWith
        //         path.replaceWith(nodes[0])
        //     } else {
        //         // 多节点用 replaceWithMultiple
        //         path.replaceWithMultiple(nodes);
        //     }
        // }
    }
}

